import { useMount } from 'ahooks';
import { App, Button, Input, Select, Switch } from 'antd';
import { useCallback, useMemo, useState } from 'react';

import FormLabel from '@/components/MyBox/FormLabel';
import MyModal from '@/components/MyModal';
import QuestionTip from '@/components/tooltip/QuestionTip';
import { t } from '@/locales/i18n';
import {
  FlowNodeInputTypeEnum,
  FlowValueTypeMap,
  WorkflowIOValueTypeEnum,
} from '@/types/workflow/constant';
import { CustomFieldConfigType, FlowNodeInputItemType } from '@/types/workflow/io';

const { TextArea } = Input;

const PluginOutputEditModal = ({
  customOutputConfig,
  defaultOutput,
  keys,
  onClose,
  onSubmit,
}: {
  customOutputConfig: CustomFieldConfigType;
  defaultOutput: FlowNodeInputItemType;
  keys: string[];
  onClose: () => void;
  onSubmit: (e: { data: FlowNodeInputItemType; isChangeKey: boolean }) => void;
}) => {
  const isEdit = !!defaultOutput.key;
  const { message } = App.useApp();

  const [data, setData] = useState<FlowNodeInputItemType>({
    ...defaultOutput,
    isToolOutput: defaultOutput.isToolOutput !== false,
  });

  const inputType = FlowNodeInputTypeEnum.reference;

  // value type select
  const showValueTypeSelect = useMemo(() => {
    if (
      !customOutputConfig.selectValueTypeList ||
      customOutputConfig.selectValueTypeList.length <= 1
    )
      return false;
    if (inputType === FlowNodeInputTypeEnum.reference) return true;

    return false;
  }, [customOutputConfig.selectValueTypeList, inputType]);
  const valueTypeSelectList = useMemo(() => {
    if (!customOutputConfig.selectValueTypeList) return [];

    const dataTypeSelectList = Object.values(FlowValueTypeMap).map((item) => ({
      label: t(item.label as any),
      value: item.value,
    }));

    return dataTypeSelectList.filter((item) =>
      customOutputConfig.selectValueTypeList?.includes(item.value),
    );
  }, [customOutputConfig.selectValueTypeList]);

  const valueType = useMemo(() => data.valueType, [data.valueType]);

  useMount(() => {
    if (
      customOutputConfig.selectValueTypeList &&
      customOutputConfig.selectValueTypeList.length > 0 &&
      !valueType
    ) {
      const valueType = customOutputConfig.selectValueTypeList[0];

      setData((prev) => {
        return {
          ...prev,
          valueType,
        };
      });
    }
  });

  const onSubmitSuccess = useCallback(
    (data: FlowNodeInputItemType) => {
      const isChangeKey = defaultOutput.key !== data.key;

      if (keys.includes(data.key)) {
        if (!isEdit || isChangeKey) {
          message.warning(t('field_name_already_exists'));
          return;
        }
      }

      data.key = data?.key?.trim();
      data.label = data.key;

      onSubmit({
        data,
        isChangeKey,
      });
      onClose();
    },
    [defaultOutput.key, keys, onSubmit, onClose, isEdit, message],
  );

  return (
    <MyModal
      isOpen
      iconSrc="menu_set"
      title={isEdit ? t('edit_output') : t('add_new_output')}
      // overflow={'unset'}
      className=" overflow-hidden"
    >
      <div className="flex w-full overflow-auto">
        <div className="flex w-full">
          {showValueTypeSelect && (
            <div className="flex items-center">
              <FormLabel>{t('core.module.Data Type')}</FormLabel>
              <div className="flex-1">
                <Select
                  className="w-full"
                  popupClassName="workflow-dropdown"
                  options={valueTypeSelectList.filter(
                    (item) => item.value !== WorkflowIOValueTypeEnum.arrayAny,
                  )}
                  value={valueType}
                  onChange={(e) => {
                    setData((prev) => {
                      return {
                        ...prev,
                        valueType: e,
                      };
                    });
                  }}
                />
              </div>
            </div>
          )}
          {/* key */}
          <div className="mt-3 flex items-center gap-2">
            <FormLabel required>{t('core.module.Field Name')}</FormLabel>
            <Input
              className="bg-gray-500"
              value={data.key}
              onChange={(e) => {
                setData((prev) => {
                  return {
                    ...prev,
                    key: e.target.value,
                  };
                });
              }}
              placeholder="appointment/sql"
            />
          </div>

          <div className="mt-3 items-center">
            <FormLabel>{t('input_description')}</FormLabel>
            <TextArea
              className="bg-gray-500"
              value={data.description}
              onChange={(e) => {
                setData((prev) => {
                  return {
                    ...prev,
                    description: e.target.value,
                  };
                });
              }}
            />
          </div>
          <div className="mt-3 flex items-center">
            <FormLabel>{t('is_tool_output_label')}</FormLabel>
            <QuestionTip title={t('plugin_output_tool')} className="mt-1" />
            <div className="flex-1" />
            <Switch
              checked={data.isToolOutput}
              onChange={(e) => {
                setData((prev) => {
                  return {
                    ...prev,
                    isToolOutput: e,
                  };
                });
              }}
            />
          </div>
        </div>
      </div>
      <div className="ml-auto mt-4 flex gap-3">
        <Button onClick={onClose}>{t('common.Close')}</Button>
        <Button
          type="primary"
          onClick={() => {
            onSubmitSuccess(data);
          }}
        >
          {t('common.Confirm')}
        </Button>
      </div>
    </MyModal>
  );
};

export default PluginOutputEditModal;

export const defaultOutput: FlowNodeInputItemType = {
  renderTypeList: [FlowNodeInputTypeEnum.reference],
  valueType: WorkflowIOValueTypeEnum.string,
  canEdit: true,
  key: '',
  label: '',
  isToolOutput: true,
};
